/*
 * StreamBuffer.h
 *
 *  Created on: Mar 27, 2013
 *      Author: root
 */

#ifndef STREAMBUFFER_H_
#define STREAMBUFFER_H_

#include "smart_lock.h"

/*
*stream_buf define
*/
#define IO_CHUNK_SIZE  0xffff /*io buf chunk size length*/
#define AV_CHUNK_SIZE  0xffff * 2 /*128 KB*/
#define STREAM_AV_CHUNK_COUNT 40 /*stream cach packet count*/
#define TS_MAX_PACK_SIZE  256 /*ts packet buf size 256 bytes*/
#define TS_MAX_CACH_COUNT 512 /*ts packet cach count 512*/

/*
*stream packet
*/
struct AVPacket
{
	ubyte		*data;
	uint64_t	data_size;
	uint64_t	data_len;
	uint16_t    stream_id;
	uint64_t    pkt_index;
	uint64_t    chunck_size;
	uint64_t    chunck_offset;
	uint32_t    pts;
	uint32_t    dts;
	/*
	*frame_type:
	*0,unkown frame
	*1,audio frame,
	*2,video frame,
	*3,video key frame
	*/
	uint32_t	frame_type;
	uint64_t    last_frame_offset;
	uint64_t    last_frame_size;
	uint64_t    last_key_frame_offset;
	AVPacket    *next;
	AVPacket    *prev;
	AVPacket()
	{
		this->data = NULL;
		this->data_size = 0;
		this->data_len = 0;
		this->pkt_index = 0;
		this->chunck_size = 0;
		this->chunck_offset = 0;

		this->pts = 0;
		this->dts = 0;

		this->stream_id = 0;
		this->frame_type = 0;
		this->last_frame_offset = 0;
		this->last_frame_size = 0;
		this->last_key_frame_offset = 0;

		this->next = NULL;
		this->prev = NULL;
	}
};

/**
 * live stream buffer class
 */
class StreamBuffer {
public:
	StreamBuffer();
	virtual ~StreamBuffer();

	/*stream buf*/
	int init(uint16_t max_stream_num,uint16_t max_stream_pkt_count = STREAM_AV_CHUNK_COUNT);
	int alloc_pkt(AVPacket **ptk);
	int free_pkt(AVPacket *pkt);
	int free_pkt(AVPacket *hpkt,int count);

	int get_current_packet_count(void);
	int get_free_packet_count(void);
	int get_total_count(void);

private:
	int current_packet_count;
	int total_count;
	ubyte * buf;
	stack<AVPacket *> free_pkt_pool;
	smart_lock buf_lock;
};

#endif /* STREAMBUFFER_H_ */
